/**
 * 翼支付APP金豆0点抢兑话费脚本 - 增强版
 * 适用于青龙面板
 * 
 * 增强功能：
 * 1. 支持多种兑换金额尝试
 * 2. 智能时间控制
 * 3. 详细的执行日志
 * 4. 错误恢复机制
 * 5. 兑换结果通知
 */

// 环境变量配置
const CONFIG = {
    // 基础配置
    phone: process.env.YIFUPAY_PHONE || '',
    password: process.env.YIFUPAY_PASSWORD || '',
    
    // 兑换配置
    exchangeAmounts: (process.env.YIFUPAY_EXCHANGE_AMOUNTS || '5,10,20').split(',').map(Number), // 尝试的兑换金额
    minJindou: parseInt(process.env.YIFUPAY_MIN_JINDOU) || 100,
    
    // 时间控制
    startTime: process.env.YIFUPAY_START_TIME || '23:55', // 开始准备时间
    endTime: process.env.YIFUPAY_END_TIME || '00:05',     // 结束时间窗口
    
    // 重试配置
    retryCount: parseInt(process.env.YIFUPAY_RETRY_COUNT) || 3,
    retryDelay: parseInt(process.env.YIFUPAY_RETRY_DELAY) || 1000,
    
    // 通知配置
    notifyOnSuccess: process.env.YIFUPAY_NOTIFY_SUCCESS === 'true',
    notifyOnFailure: process.env.YIFUPAY_NOTIFY_FAILURE === 'true',
    
    // 调试模式
    debug: process.env.YIFUPAY_DEBUG === 'true'
};

// 翼支付API配置
const API_CONFIG = {
    baseUrl: 'https://api.bestpay.com.cn',
    loginUrl: '/login',
    jindouUrl: '/jindou/query',
    exchangeUrl: '/jindou/exchange',
    userAgent: 'BestPay/8.0.0 (Android 11; SM-G975F)',
    timeout: 10000 // 10秒超时
};

/**
 * 日志输出函数
 */
function log(message, type = 'info') {
    const timestamp = new Date().toLocaleString('zh-CN');
    const prefix = {
        'info': '📱',
        'success': '✅',
        'error': '❌',
        'warning': '⚠️',
        'debug': '🔍'
    }[type] || '📱';
    
    console.log(`[${timestamp}] ${prefix} ${message}`);
    
    // 调试模式下输出更多详细信息
    if (CONFIG.debug && type === 'debug') {
        console.trace();
    }
}

/**
 * 延迟函数
 */
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

/**
 * 格式化时间
 */
function formatTime(date = new Date()) {
    return date.toLocaleString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit'
    });
}

/**
 * 检查是否在执行时间窗口内
 */
function isInTimeWindow() {
    const now = new Date();
    const currentTime = now.getHours() * 60 + now.getMinutes();
    
    // 解析开始和结束时间
    const [startHour, startMin] = CONFIG.startTime.split(':').map(Number);
    const [endHour, endMin] = CONFIG.endTime.split(':').map(Number);
    
    const startTime = startHour * 60 + startMin;
    const endTime = endHour * 60 + endMin;
    
    // 处理跨天情况（如23:55到00:05）
    if (startTime > endTime) {
        return currentTime >= startTime || currentTime <= endTime;
    } else {
        return currentTime >= startTime && currentTime <= endTime;
    }
}

/**
 * 计算到0点的倒计时
 */
function getCountdownToMidnight() {
    const now = new Date();
    const midnight = new Date(now);
    midnight.setHours(24, 0, 0, 0); // 设置为明天的0点
    
    const diff = midnight - now;
    const hours = Math.floor(diff / (1000 * 60 * 60));
    const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
    const seconds = Math.floor((diff % (1000 * 60)) / 1000);
    
    return { hours, minutes, seconds, total: diff };
}

/**
 * 生成请求头
 */
function generateHeaders(token = '') {
    return {
        'Content-Type': 'application/json',
        'User-Agent': API_CONFIG.userAgent,
        'Accept': 'application/json',
        ...(token && { 'Authorization': `Bearer ${token}` })
    };
}

/**
 * 安全的HTTP请求
 */
async function safeRequest(url, options = {}, retries = 3) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), API_CONFIG.timeout);
    
    try {
        const response = await fetch(url, {
            ...options,
            signal: controller.signal,
            headers: {
                ...generateHeaders(),
                ...options.headers
            }
        });
        
        clearTimeout(timeoutId);
        
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        return await response.json();
    } catch (error) {
        clearTimeout(timeoutId);
        
        if (retries > 0) {
            log(`请求失败，${CONFIG.retryDelay}ms后重试... (剩余${retries}次)`, 'warning');
            await sleep(CONFIG.retryDelay);
            return safeRequest(url, options, retries - 1);
        }
        
        throw error;
    }
}

/**
 * 翼支付登录
 */
async function login() {
    try {
        log('开始登录翼支付账户...');
        
        const loginData = {
            phone: CONFIG.phone,
            password: CONFIG.password,
            deviceId: generateDeviceId(),
            timestamp: Date.now()
        };
        
        log(`登录请求数据: ${JSON.stringify({...loginData, password: '***'})}`, 'debug');
        
        const response = await safeRequest(`${API_CONFIG.baseUrl}${API_CONFIG.loginUrl}`, {
            method: 'POST',
            body: JSON.stringify(loginData)
        });
        
        if (response.code === 0) {
            storeToken(response.data.token);
            log(`登录成功，手机号：${CONFIG.phone}`, 'success');
            return { success: true, token: response.data.token };
        } else {
            throw new Error(`登录失败: ${response.message}`);
        }
    } catch (error) {
        log(`登录异常: ${error.message}`, 'error');
        return { success: false, error: error.message };
    }
}

/**
 * 获取金豆数量
 */
async function getJindouCount() {
    try {
        log('查询金豆数量...');
        
        const token = getStoredToken();
        const response = await safeRequest(`${API_CONFIG.baseUrl}${API_CONFIG.jindouUrl}`, {
            method: 'GET',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        
        if (response.code === 0) {
            const jindouCount = response.data.jindouCount;
            log(`当前金豆数量: ${jindouCount}`, 'info');
            return { success: true, count: jindouCount };
        } else {
            throw new Error(`查询失败: ${response.message}`);
        }
    } catch (error) {
        log(`查询金豆异常: ${error.message}`, 'error');
        return { success: false, error: error.message };
    }
}

/**
 * 兑换话费
 */
async function exchangePhoneBill(amount) {
    try {
        log(`开始兑换话费，金额: ${amount}元...`);
        
        const token = getStoredToken();
        const exchangeData = {
            amount: amount,
            type: 'phone_bill',
            timestamp: Date.now()
        };
        
        log(`兑换请求数据: ${JSON.stringify(exchangeData)}`, 'debug');
        
        const response = await safeRequest(`${API_CONFIG.baseUrl}${API_CONFIG.exchangeUrl}`, {
            method: 'POST',
            headers: { 'Authorization': `Bearer ${token}` },
            body: JSON.stringify(exchangeData)
        });
        
        if (response.code === 0) {
            log(`话费兑换成功！兑换金额: ${amount}元`, 'success');
            return { success: true, data: response.data };
        } else {
            throw new Error(`兑换失败: ${response.message}`);
        }
    } catch (error) {
        log(`兑换异常: ${error.message}`, 'error');
        return { success: false, error: error.message };
    }
}

/**
 * 智能兑换策略
 */
async function smartExchange() {
    log('开始智能兑换策略...');
    
    // 按金额从小到大尝试
    for (const amount of CONFIG.exchangeAmounts) {
        log(`尝试兑换 ${amount} 元话费...`);
        
        for (let attempt = 1; attempt <= CONFIG.retryCount; attempt++) {
            try {
                const result = await exchangePhoneBill(amount);
                
                if (result.success) {
                    return {
                        success: true,
                        amount: amount,
                        attempt: attempt,
                        message: `成功兑换 ${amount} 元话费`
                    };
                }
                
                log(`第 ${attempt} 次尝试失败: ${result.error}`, 'warning');
                
                if (attempt < CONFIG.retryCount) {
                    await sleep(CONFIG.retryDelay);
                }
            } catch (error) {
                log(`第 ${attempt} 次尝试异常: ${error.message}`, 'error');
            }
        }
    }
    
    return {
        success: false,
        message: '所有金额和尝试次数都已用完'
    };
}

/**
 * 发送通知
 */
async function sendNotification(message, type = 'success') {
    if (type === 'success' && !CONFIG.notifyOnSuccess) return;
    if (type === 'failure' && !CONFIG.notifyOnFailure) return;
    
    try {
        // 这里可以集成各种通知方式
        // 企业微信、钉钉、邮件、短信等
        
        log(`📢 通知: ${message}`);
        
        // 示例：企业微信通知
        if (process.env.WECOM_WEBHOOK) {
            await fetch(process.env.WECOM_WEBHOOK, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    msgtype: 'text',
                    text: {
                        content: `翼支付金豆兑换结果: ${message}`
                    }
                })
            });
        }
        
        // 示例：钉钉通知
        if (process.env.DINGTALK_WEBHOOK) {
            await fetch(process.env.DINGTALK_WEBHOOK, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    msgtype: 'text',
                    text: {
                        content: `翼支付金豆兑换结果: ${message}`
                    }
                })
            });
        }
        
    } catch (error) {
        log(`发送通知失败: ${error.message}`, 'error');
    }
}

/**
 * 等待到0点并执行兑换
 */
async function waitAndExecute() {
    log('开始等待0点执行兑换...');
    
    while (isInTimeWindow()) {
        const countdown = getCountdownToMidnight();
        const now = new Date();
        
        // 检查是否到达0点
        if (now.getHours() === 0 && now.getMinutes() === 0) {
            log('🕛 到达0点，开始执行兑换！');
            
            const result = await smartExchange();
            
            if (result.success) {
                await sendNotification(result.message, 'success');
                return result;
            } else {
                await sendNotification('兑换失败: ' + result.message, 'failure');
                return result;
            }
        }
        
        // 显示倒计时
        if (countdown.total > 0 && countdown.total < 600000) { // 10分钟内显示倒计时
            log(`距离0点还有: ${countdown.hours}时${countdown.minutes}分${countdown.seconds}秒`);
        }
        
        // 每秒检查一次
        await sleep(1000);
    }
    
    log('超出执行时间窗口，程序退出', 'warning');
    return { success: false, message: '超出执行时间窗口' };
}

/**
 * 工具函数
 */
function generateDeviceId() {
    return 'android_' + Math.random().toString(36).substr(2, 16);
}

function getStoredToken() {
    return process.env.YIFUPAY_TOKEN || '';
}

function storeToken(token) {
    process.env.YIFUPAY_TOKEN = token;
}

/**
 * 主函数
 */
async function main() {
    const startTime = Date.now();
    
    try {
        log('=== 翼支付金豆0点抢兑话费脚本开始执行 ===');
        log(`执行时间: ${formatTime()}`);
        
        // 检查配置
        if (!CONFIG.phone || !CONFIG.password) {
            const errorMsg = '请配置环境变量: YIFUPAY_PHONE 和 YIFUPAY_PASSWORD';
            log(errorMsg, 'error');
            await sendNotification(errorMsg, 'failure');
            return;
        }
        
        // 检查执行时间窗口
        if (!isInTimeWindow()) {
            const errorMsg = `当前不在执行时间窗口内 (${CONFIG.startTime} - ${CONFIG.endTime})`;
            log(errorMsg, 'warning');
            return;
        }
        
        // 登录
        const loginResult = await login();
        if (!loginResult.success) {
            const errorMsg = `登录失败: ${loginResult.error}`;
            log(errorMsg, 'error');
            await sendNotification(errorMsg, 'failure');
            return;
        }
        
        // 查询金豆数量
        const jindouResult = await getJindouCount();
        if (!jindouResult.success) {
            const errorMsg = `查询金豆失败: ${jindouResult.error}`;
            log(errorMsg, 'error');
            await sendNotification(errorMsg, 'failure');
            return;
        }
        
        // 检查金豆数量
        if (jindouResult.count < CONFIG.minJindou) {
            const errorMsg = `金豆数量不足，当前: ${jindouResult.count}, 需要: ${CONFIG.minJindou}`;
            log(errorMsg, 'warning');
            await sendNotification(errorMsg, 'failure');
            return;
        }
        
        // 等待并执行兑换
        const result = await waitAndExecute();
        
        // 执行结果统计
        const endTime = Date.now();
        const duration = Math.round((endTime - startTime) / 1000);
        
        if (result.success) {
            log(`=== 脚本执行完成 - 兑换成功 (耗时: ${duration}秒) ===`, 'success');
        } else {
            log(`=== 脚本执行完成 - 兑换失败 (耗时: ${duration}秒) ===`, 'error');
        }
        
    } catch (error) {
        const errorMsg = `脚本执行异常: ${error.message}`;
        log(errorMsg, 'error');
        await sendNotification(errorMsg, 'failure');
    }
}

// 如果直接运行此脚本
if (require.main === module) {
    main().catch(error => {
        log(`未捕获的异常: ${error.message}`, 'error');
        process.exit(1);
    });
}

// 导出函数供青龙面板调用
module.exports = {
    main,
    config: CONFIG
};